Add translatable/context and comment attributes on <col> tags under a
authorJohan Dahlin <johan@gnome.org>
Sun, 2 Mar 2008 01:14:48 +0000 (01:14 +0000)
committerJohan Dahlin <johan@src.gnome.org>
Sun, 2 Mar 2008 01:14:48 +0000 (01:14 +0000)
2008-02-29  Johan Dahlin  <johan@gnome.org>

* demos/gtk-demo/demo.ui:
* gtk/gtkbuilderparser.c:
* gtk/gtkbuilderprivate.h:
* gtk/gtkliststore.c:
* tests/buildertest.c:
Add translatable/context and comment attributes on
<col> tags under a GtkListStore. Refactor parts of the
translation api and make it available inside gtk+ itself.
Update tests and example.
Fixes a part of #518642

svn path=/trunk/; revision=19685

ChangeLog
demos/gtk-demo/demo.ui
gtk/gtkbuilderparser.c
gtk/gtkbuilderprivate.h
gtk/gtkliststore.c
tests/buildertest.c

index 4f9a9c9aedd02650d9d8fb07f08deccd20ec4129..ac23015c1122f5d0d3c0a1ae58ee01c1bcbe12d0 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2008-02-29  Johan Dahlin  <johan@gnome.org>
+
+       * demos/gtk-demo/demo.ui:
+       * gtk/gtkbuilderparser.c:
+       * gtk/gtkbuilderprivate.h:
+       * gtk/gtkliststore.c:
+       * tests/buildertest.c:
+       Add translatable/context and comment attributes on
+       <col> tags under a GtkListStore. Refactor parts of the
+       translation api and make it available inside gtk+ itself.
+       Update tests and example.
+       Fixes a part of #518642
+
 2008-02-29  Johan Dahlin  <johan@gnome.org>
 
        * gtk/gtkbuilder.c:
index 9d27c85cea8f52f10cee7a3bb9bf49745599aff8..57dd232505a4803b70bb0fd7bb4dc9fc525417b3 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
-<interface>
+<interface domain="gtk20">
     <object class="GtkListStore" id="liststore1">
       <columns>
         <column type="gchararray"/>
@@ -9,16 +9,16 @@
       </columns>
       <data>
         <row>
-          <col id="0">John</col>
-          <col id="1">Doe</col>
+          <col id="0" translatable="yes">John</col>
+          <col id="1" translatable="yes">Doe</col>
           <col id="2">25</col>
-          <col id="3">This is the John Doe row</col>
+          <col id="3" translatable="yes">This is the John Doe row</col>
         </row>
         <row>
-          <col id="0">Mary</col>
-          <col id="1">Dole</col>
+          <col id="0" translatable="yes">Mary</col>
+          <col id="1" translatable="yes">Unknown</col>
           <col id="2">50</col>
-          <col id="3">This is the Mary Dole row</col>
+          <col id="3" translatable="yes">This is the Mary Unknown row</col>
         </row>
       </data>
     </object>
index 76e633e8741ea406c966982cdc7b0132b5e9cd5d..d6d69a46cfa6c3ab4b4ce748f16b3f74e8a23e32 100644 (file)
@@ -791,6 +791,21 @@ dpgettext (const char *domain,
   return translation;
 }
 
+gchar *
+_gtk_builder_parser_translate (const gchar *domain,
+                              const gchar *context,
+                              const gchar *text)
+{
+  const char *s;
+
+  if (context)
+    s = dpgettext (domain, context, text);
+  else
+    s = dgettext (domain, text);
+
+  return g_strdup (s);
+}
+
 /* Called for close tags </foo> */
 static void
 end_element (GMarkupParseContext *context,
@@ -841,22 +856,15 @@ end_element (GMarkupParseContext *context,
 
           if (prop_info->translatable && prop_info->text->len)
             {
-              const char *text;
-
-              if (prop_info->context)
-                text = dpgettext (data->domain,
-                                  prop_info->context,
-                                  prop_info->text->str);
-              else
-                text = dgettext (data->domain, prop_info->text->str);
-
-              prop_info->data = g_strdup (text);
+             prop_info->data = _gtk_builder_parser_translate (data->domain,
+                                                              prop_info->context,
+                                                              prop_info->text->str);
               g_string_free (prop_info->text, TRUE);
             }
           else
             {
-              prop_info->data = prop_info->text->str;
-              g_string_free (prop_info->text, FALSE);
+              prop_info->data = g_string_free (prop_info->text, FALSE);
+              
             }
 
           object_info->properties =
index 2cbb322bece71f2c2f24f617c120af9bc33d49df..1a45aca2369d2f754c3efb223ea44cea3f1adb60 100644 (file)
@@ -97,6 +97,7 @@ typedef struct {
 
 typedef GType (*GTypeGetFunc) (void);
 
+/* Things only GtkBuilder should use */
 void _gtk_builder_parser_parse_buffer (GtkBuilder *builder,
                                        const gchar *filename,
                                        const gchar *buffer,
@@ -112,6 +113,8 @@ void      _gtk_builder_add_signals (GtkBuilder *builder,
 void      _gtk_builder_finish (GtkBuilder *builder);
 void _free_signal_info (SignalInfo *info,
                         gpointer user_data);
+
+/* Internal API which might be made public at some point */
 gboolean _gtk_builder_boolean_from_string (const gchar  *string,
                                           gboolean     *value,
                                           GError      **error);
@@ -119,5 +122,8 @@ gboolean  _gtk_builder_flags_from_string (GType       type,
                                          const char *string,
                                          guint      *value,
                                          GError    **error);
+gchar * _gtk_builder_parser_translate (const gchar *domain,
+                                      const gchar *context,
+                                      const gchar *text);
 
 #endif /* __GTK_BUILDER_PRIVATE_H__ */
index 3557a7cf36cbd013717c7bfa41d7cf056ff47375..3e56ef4b6ea7650a2463161a235b1ca27fcf0fb5 100644 (file)
@@ -28,6 +28,7 @@
 #include "gtktreednd.h"
 #include "gtkintl.h"
 #include "gtkbuildable.h"
+#include "gtkbuilderprivate.h"
 #include "gtkalias.h"
 
 #define GTK_LIST_STORE_IS_SORTED(list) (((GtkListStore*)(list))->sort_column_id != GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID)
@@ -2042,18 +2043,26 @@ gtk_list_store_insert_with_valuesv (GtkListStore *list_store,
  *   <column type="..."/>
  * </columns>
  */
+typedef struct {
+  gboolean translatable;
+  gchar *context;
+  int id;
+} ColInfo;
+
 typedef struct {
   GtkBuilder *builder;
   GObject *object;
   GSList *column_type_names;
   GType *column_types;
   GValue *values;
-  gint *columns;
+  gint *colids;
+  ColInfo **columns;
   gint last_row;
   gint n_columns;
   gint row_column;
   GQuark error_quark;
   gboolean is_data;
+  const gchar *domain;
 } SubParserData;
 
 static void
@@ -2070,6 +2079,9 @@ list_store_start_element (GMarkupParseContext *context,
   if (strcmp (element_name, "col") == 0)
     {
       int i, id = -1;
+      gchar *context = NULL;
+      gboolean translatable = FALSE;
+      ColInfo *info;
 
       if (data->row_column >= data->n_columns)
        g_set_error (error, data->error_quark, 0,
@@ -2082,14 +2094,35 @@ list_store_start_element (GMarkupParseContext *context,
            id = atoi (values[i]);
            if (errno)
              g_set_error (error, data->error_quark, 0,
-                          "the id tag %s could not be converted to an integer", values[i]);
+                          "the id tag %s could not be converted to an integer",
+                          values[i]);
+         }
+       else if (strcmp (names[i], "translatable") == 0)
+         {
+           if (!_gtk_builder_boolean_from_string (values[i], &translatable,
+                                                  error))
+             return;
+         }
+       else if (strcmp (names[i], "comments") == 0)
+         {
+           /* do nothing, comments are for translators */
+         }
+       else if (strcmp (names[i], "context") == 0) 
+         {
+           context = g_strdup (values[i]);
          }
 
       if (id == -1)
        g_set_error (error, data->error_quark, 0,
                     "<col> needs an id attribute");
+      
+      info = g_slice_new0 (ColInfo);
+      info->translatable = translatable;
+      info->context = context;
+      info->id = id;
 
-      data->columns[data->row_column] = id;
+      data->colids[data->row_column] = id;
+      data->columns[data->row_column] = info;
       data->row_column++;
       data->is_data = TRUE;
     }
@@ -2127,11 +2160,17 @@ list_store_end_element (GMarkupParseContext *context,
       gtk_list_store_insert_with_valuesv (GTK_LIST_STORE (data->object),
                                          &iter,
                                          data->last_row,
-                                         data->columns,
+                                         data->colids,
                                          data->values,
                                          data->row_column);
       for (i = 0; i < data->row_column; i++)
-       g_value_unset (&data->values[i]);
+       {
+         ColInfo *info = data->columns[i];
+         g_free (info->context);
+         g_slice_free (ColInfo, info);
+         data->columns[i] = NULL;
+         g_value_unset (&data->values[i]);
+       }
       g_free (data->values);
       data->values = g_new0 (GValue, data->n_columns);
       data->last_row++;
@@ -2189,13 +2228,30 @@ list_store_text (GMarkupParseContext *context,
   gint i;
   GError *tmp_error = NULL;
   gchar *string;
+  ColInfo *info;
   
   if (!data->is_data)
     return;
 
   i = data->row_column - 1;
+  info = data->columns[i];
 
   string = g_strndup (text, text_len);
+  if (info->translatable && text_len)
+    {
+      gchar *translated;
+
+      /* FIXME: This will not use the domain set in the .ui file,
+       * since the parser is not telling the builder about the domain.
+       * However, it will work for gtk_builder_set_translation_domain() calls.
+       */
+      translated = _gtk_builder_parser_translate (data->domain,
+                                                 info->context,
+                                                 string);
+      g_free (string);
+      string = translated;
+    }
+
   if (!gtk_builder_value_from_string_type (data->builder,
                                           data->column_types[i],
                                           string,
@@ -2255,11 +2311,13 @@ gtk_list_store_buildable_custom_tag_start (GtkBuildable  *buildable,
       parser_data->builder = builder;
       parser_data->object = G_OBJECT (buildable);
       parser_data->values = g_new0 (GValue, n_columns);
-      parser_data->columns = g_new0 (gint, n_columns);
+      parser_data->colids = g_new0 (gint, n_columns);
+      parser_data->columns = g_new0 (ColInfo*, n_columns);
       parser_data->column_types = GTK_LIST_STORE (buildable)->column_headers;
       parser_data->n_columns = n_columns;
       parser_data->last_row = 0;
       parser_data->error_quark = g_quark_from_static_string ("GtkListStore");
+      parser_data->domain = gtk_builder_get_translation_domain (builder);
       
       *parser = list_store_parser;
       *data = parser_data;
@@ -2287,6 +2345,17 @@ gtk_list_store_buildable_custom_tag_end (GtkBuildable *buildable,
     }
   else if (strcmp (tagname, "data") == 0)
     {
+      int i;
+      for (i = 0; i < sub->n_columns; i++)
+       {
+         ColInfo *info = sub->columns[i];
+         if (info)
+           {
+             g_free (info->context);
+             g_slice_free (ColInfo, info);
+           }
+       }
+      g_free (sub->colids);
       g_free (sub->columns);
       g_free (sub->values);
       g_slice_free (SubParserData, sub);
index fb6f7104d32d9fda9b1d27884710a99b497994ff..6649aa18b6ca35ef5bbe9e136edd64a388f13796 100644 (file)
@@ -527,9 +527,9 @@ test_list_store (void)
     "    </columns>"
     "    <data>"
     "      <row>"
-    "        <col id=\"0\">John</col>"
-    "        <col id=\"1\">Doe</col>"
-    "        <col id=\"2\">25</col>"
+    "        <col id=\"0\" translatable=\"yes\">_Quit</col>"
+    "        <col id=\"1\" context=\"foo\">Doe</col>"
+    "        <col id=\"2\" comment=\"foobar\">25</col>"
     "      </row>"
     "      <row>"
     "        <col id=\"0\">Johan</col>"